package com.CST.service.impl;

import com.CST.common.api.Response;
import com.CST.common.constant.Constants;
import com.CST.common.enumPackge.EnumAmortizationType;
import com.CST.dto.CostReadyDTO;
import com.CST.dto.DateDTO;
import com.CST.entity.*;
import com.CST.mapper.cst.*;
import com.CST.mapper.dataplatform.BdDepartmentMapper;
import com.CST.mapper.dataplatform.BdEnumdetailMapper;
import com.CST.mapper.dataplatform.BdOrganizationMapper;
import com.CST.service.IAllocationCostService;
import com.CST.service.IBdEnumdetailService;
import com.CST.util.HttpUtil;
import com.CST.vo.ReportAmortizationDataVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AllocationCostServiceImpl implements IAllocationCostService {


    @Autowired
    private BaseCostMapper baseCostMapper;

    @Autowired
    private RuleCompelamortizationMapper ruleCompelamortizationMapper;

    @Autowired
    private BdDepartmentMapper bdDepartmentMapper;

    @Autowired
    private BdEnumdetailMapper bdEnumdetailMapper;


    @Autowired
    private AmortizationDataMapper amortizationDataMapper;

    @Autowired
    private BdOrganizationMapper organizationMapper;

    @Autowired
    private BdOrganizationMapper bdOrganizationMapper;

    /**
     * 科室分摊模块
     *
     * @param dateDTO
     * @return
     */

    //一键分摊
    @Transactional(rollbackFor = Exception.class)
    public Response quickAmortization(DateDTO dateDTO) {
        Response response = new Response();
        try {
            dateDTO.setTableIncome("BASE_IN_COME_".concat(String.valueOf(dateDTO.getYear())));
            dateDTO.setTableCost("BASE_COST_".concat(String.valueOf(dateDTO.getYear())));
            dateDTO.setTableCoefficient("ALLOCATION_COEFFICIENT_".concat(String.valueOf(dateDTO.getYear())));
            // 1.获取组织架构
            List<BdDepartment> bdDepartmentList = bdDepartmentMapper.selectList(null);


            // 2.获取成本数据
            CostReadyDTO costReady = readyAmortization(dateDTO);
            if (costReady.getStatus().equals(false)) {
                return Response.error("成本数据分摊出错,请联系管理员");
            }

            List<Direct> costSource = costReady.getCostSource();

            //拿到分摊表(强制分摊&定向分摊)
            List<RuleCompelamortization> ruleCompelAmortizationList = ruleCompelamortizationMapper.getDirectToCompelRule(dateDTO);
           List<RuleCompelamortization> collect = ruleCompelAmortizationList.stream().filter(t -> t.getType().equals("Compel")).collect(Collectors.toList());
            List<Direct> resultCostSource = getCostSourceByRule(bdDepartmentList, collect, costSource, EnumAmortizationType.DXQZ,dateDTO);
//          List<RuleCompelamortization> collect1 = ruleCompelAmortizationList.stream().filter(t -> t.getType().equals("Direct")).collect(Collectors.toList());
//            resultCostSource = getCostSourceByRule1(bdDepartmentList, collect1, resultCostSource, EnumAmortizationType.DX);
            //插入数据库 AMORTIZATION_DATA 科室分摊前数据
            int deleteRet = amortizationDataMapper.deleteByYearMonth(dateDTO);

            int total = resultCostSource.size();//为防止插入字符超过最大数,分批插入
            int fromIndex = 0;
            List<Direct> insertList = new ArrayList<>();
            for (int i = 0; i < resultCostSource.size(); i++) {
                Direct item = resultCostSource.get(i);
                fromIndex++;
                insertList.add(item);
                if (fromIndex % 20 == 0 && fromIndex <= total) {
                    amortizationDataMapper.insertBatchAmortizationData(insertList);
                    insertList = new ArrayList<>();
                }
            }
            if (CollectionUtils.isNotEmpty(insertList)) {
                amortizationDataMapper.insertBatchAmortizationData(insertList);
            }
//           List<RuleCompelamortization> collect1 = ruleCompelAmortizationList.stream().filter(t -> t.getType().equals("Direct")).collect(Collectors.toList());
//            resultCostSource = getCostSourceByRule(bdDepartmentList, collect1, resultCostSource, EnumAmortizationType.DXQZ,dateDTO);
            List<RuleCompelamortization> collect1 = ruleCompelAmortizationList.stream().filter(t -> t.getType().equals("Direct")).collect(Collectors.toList());
            resultCostSource = getCostSourceByRule1(bdDepartmentList, collect1, resultCostSource, EnumAmortizationType.DX);
            //特殊处理,定向分摊中会出现二次分摊情况
            List<RuleCompelamortization> towiceRule = ruleCompelamortizationMapper.towiceCheck(dateDTO);
            resultCostSource = getCostSourceByRule(bdDepartmentList, towiceRule, resultCostSource, EnumAmortizationType.DXQZ,dateDTO);

            //拿到分摊表(行政类分摊)
            List<RuleCompelamortization> ruleXZList = ruleCompelamortizationMapper.getXZRule(dateDTO);
            if (validateCoefficient(ruleXZList)) {
                return Response.error("行政类分摊系数有null值,请检查数据");
            }

            resultCostSource = getCostSourceByRule(bdDepartmentList, ruleXZList, resultCostSource, EnumAmortizationType.XZ,dateDTO);

            //插入数据库 AMORTIZATION_DATA1 科室分摊前数据
            int deleteRet1 = amortizationDataMapper.deleteByYearMonth1(dateDTO);

            int total1 = resultCostSource.size();//为防止插入字符超过最大数,分批插入
            int fromIndex1 = 0;
            List<Direct> insertList1 = new ArrayList<>();
            for (int i = 0; i < resultCostSource.size(); i++) {
                Direct item = resultCostSource.get(i);
                fromIndex1++;
                insertList1.add(item);
                if (fromIndex1 % 20 == 0 && fromIndex1 <= total1) {
                    amortizationDataMapper.insertBatchAmortizationData1(insertList1);
                    insertList1 = new ArrayList<>();
                }
            }
            if (CollectionUtils.isNotEmpty(insertList1)) {
                amortizationDataMapper.insertBatchAmortizationData1(insertList1);
            }

            //医辅类分摊
            //拿到分摊表(医辅类分摊)
            List<RuleCompelamortization> ruleYFList = ruleCompelamortizationMapper.getYFRule(dateDTO);
            if (validateCoefficient(ruleYFList)) {
                return Response.error("医辅类分摊系数有null值,请检查数据");
            }
            resultCostSource = getCostSourceByRule(bdDepartmentList, ruleYFList, resultCostSource, EnumAmortizationType.YF,dateDTO);

            //插入数据库 AMORTIZATION_DATA2 科室分摊前数据
            int deleteRet2 = amortizationDataMapper.deleteByYearMonth2(dateDTO);

            int total2 = resultCostSource.size();//为防止插入字符超过最大数,分批插入
            int fromIndex2 = 0;
            List<Direct> insertList2 = new ArrayList<>();
            for (int i = 0; i < resultCostSource.size(); i++) {
                Direct item = resultCostSource.get(i);
                fromIndex2++;
                insertList2.add(item);
                if (fromIndex2 % 20 == 0 && fromIndex2 <= total2) {
                    amortizationDataMapper.insertBatchAmortizationData2(insertList2);
                    insertList2 = new ArrayList<>();
                }
            }
            if (CollectionUtils.isNotEmpty(insertList2)) {
                amortizationDataMapper.insertBatchAmortizationData2(insertList2);
            }


            List<OrganizationInfo> noSZPBList = amortizationDataMapper.listNoSZPB(dateDTO);
            List<OrganizationInfo> listNoSZPBCL = amortizationDataMapper.listNoSZPBCL(dateDTO);

            if (CollectionUtils.isNotEmpty(noSZPBList)) {
                List<Direct> finalResultCostSource = resultCostSource;
                noSZPBList.forEach(item -> {
                    List<Direct> matchDirect = finalResultCostSource.stream().filter(t->t.getDeptCode().equals(item.getDeptCode())).collect(Collectors.toList());
                    List<OrganizationInfo> matchList = listNoSZPBCL.stream().filter(t -> t.getPDeptCode().equals(item.getPDeptCode())).collect(Collectors.toList());

                    OrganizationInfo targetInfo = matchList.stream().filter(t -> t.getExecutiveDeptCode()!=null && !t.getExecutiveDeptCode().isEmpty()).findFirst().orElse(null);
                    if (targetInfo == null) {
                        return;
                    }
                    if(CollectionUtils.isNotEmpty(matchDirect)) {
                        matchDirect.forEach(DItem->{
                            DItem.setDeptCode(targetInfo.getDeptCode());
                            DItem.setDeptName(targetInfo.getDeptName());
                        });
                    }
                });
            }
            List<Direct> filterList = new ArrayList<>();
            resultCostSource.stream().collect(Collectors.groupingBy(item -> (item.getDeptCode() + item.getAccountCode()), Collectors.toList())).forEach(
                    (id, transfer) -> {
                        transfer.stream().reduce((a,b) ->new Direct(a.getId(),a.getYear()
                                ,a.getMonth(),a.getDeptCode(),
                                a.getDeptName(),a.getAmount().add(b.getAmount()),a.getDirectCost().add(b.getDirectCost()),
                                a.getIndirectCost().add(b.getIndirectCost()),a.getAmortizationCode(),a.getAmortizationName(),a.getCostItemCode(),a.getCostItemName(),
                                a.getYard(), a.getDeptTypeId(), a.getDeptTypeName(),a.getAccountCode(),a.getAccountName(),a.getExtraA(),a.getExtraB(),a.getExtraC(),
                                a.getExtraD(),a.getExtraE(),a.getSourceDept(),a.getCoefficient(),a.getType()
                        ) ).ifPresent(filterList::add);
                    }
            );
            resultCostSource =filterList;
            //医技类分摊
            //拿到分摊表(医技类分摊)
            List<RuleCompelamortization> ruleYJList = ruleCompelamortizationMapper.getYJRule(dateDTO);
            if (validateCoefficient(ruleYJList)) {
                return Response.error("医技类分摊系数有null值,请检查数据");
            }

            //cww 药剂科特殊处理:将药剂科下面的金额全归为yjk进行分摊 start
            BdEnumdetail searchEnumDetail =new BdEnumdetail();
            searchEnumDetail.setEdParentCode("BD_Organization");
            searchEnumDetail.setEdEdId(1);
            BdEnumdetail enumDetailSource = bdEnumdetailMapper.getEnumDetailSource(searchEnumDetail).stream().findFirst().orElse(null);
            if(enumDetailSource==null)
            {
                return Response.error("医技分摊过程中未读取到默认规则");
            }
            BdOrganization searchBdOrganization =new BdOrganization();
            searchBdOrganization.setPDeptCode("7009");
            searchBdOrganization.setRuleCode(enumDetailSource.getEdExtraFirstCode());
            List<BdOrganization> yjkList = bdOrganizationMapper.getOrganizationSource(searchBdOrganization);
            List<String> yjkDeptList =new ArrayList<>();
            if(CollectionUtils.isNotEmpty(yjkList))
            {
                yjkDeptList =yjkList.stream().map(t->t.getDeptCode()).collect(Collectors.toList());
            }

            List<String> finalYjkDeptList = yjkDeptList;
            List<Direct> filterYjkCostSource =resultCostSource.stream().filter(t-> finalYjkDeptList.contains(t.getDeptCode())).collect(Collectors.toList());
            List<Direct> filterNomalCostSource =resultCostSource.stream().filter(t-> !finalYjkDeptList.contains(t.getDeptCode())).collect(Collectors.toList());

            Map<String, List<Direct>> listMap = filterYjkCostSource.stream().collect(Collectors.groupingBy(Direct::getAccountCode));
            List<Direct> newyjkList =new ArrayList<>();
            for (Object key : listMap.keySet()) {
                List<Direct> directList = listMap.get(key);
                BigDecimal totalAmount= directList.stream().map(t -> t.getAmount()).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal totalDirectCost= directList.stream().map(t -> t.getDirectCost()).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal totalIndirectCost= directList.stream().map(t -> t.getIndirectCost()).reduce(BigDecimal.ZERO, BigDecimal::add);
                Direct info =directList.get(0);
                info.setDeptCode("yjk");
//                info.setDeptName("药剂科办公室");
                info.setAmount(totalAmount);
                info.setDirectCost(totalDirectCost);
                info.setIndirectCost(totalIndirectCost);
                newyjkList.add(info);
            }

            resultCostSource =new ArrayList<>();
            resultCostSource.addAll(filterNomalCostSource);
            resultCostSource.addAll(newyjkList);
            //cww 药剂科特殊处理 end

            resultCostSource = getCostSourceByRule(bdDepartmentList, ruleYJList, resultCostSource, EnumAmortizationType.YJ,dateDTO);

            //插入数据库 AMORTIZATION_DATA3 科室分摊前数据
            int deleteRet3 = amortizationDataMapper.deleteByYearMonth3(dateDTO);

            int total3 = resultCostSource.size();//为防止插入字符超过最大数,分批插入
            int fromIndex3 = 0;
            List<Direct> insertList3 = new ArrayList<>();
            for (int i = 0; i < resultCostSource.size(); i++) {
                Direct item = resultCostSource.get(i);
                fromIndex3++;
                insertList3.add(item);
                if (fromIndex3 % 20 == 0 && fromIndex3 <= total3) {
                    amortizationDataMapper.insertBatchAmortizationData3(insertList3);
                    insertList3 = new ArrayList<>();
                }
            }
            if (CollectionUtils.isNotEmpty(insertList3)) {
                amortizationDataMapper.insertBatchAmortizationData3(insertList3);
            }

            // 获取未完整分摊科室
//            List<AmortizationData> unAmortizationData = amortizationDataMapper.listClinicalAmortizationDataByDate(dateDTO, null, false, null);
//            ReportAmortizationDataVO reportAmortizationDataVO = new ReportAmortizationDataVO();
//            reportAmortizationDataVO.setDeptCode("BBBBBBBBBB");
//            reportAmortizationDataVO.setDeptName("未完整分摊科室");
//            sortData(unAmortizationData, reportAmortizationDataVO);
            return Response.success("成本数据分摊成功");
        } catch (Exception ex) {
            return Response.error("成本数据分摊出错,请联系管理员");
        }
    }


    @Override
    public Response amortization(DateDTO dateDTO) {
        Response response = new Response();
        try {
            dateDTO.setTableIncome("BASE_IN_COME_".concat(String.valueOf(dateDTO.getYear())));
            dateDTO.setTableCost("BASE_COST_".concat(String.valueOf(dateDTO.getYear())));
            dateDTO.setTableCoefficient("ALLOCATION_COEFFICIENT_".concat(String.valueOf(dateDTO.getYear())));
            // 1.获取组织架构
            List<BdDepartment> bdDepartmentList = bdDepartmentMapper.selectList(null);


            // 2.获取成本数据
            CostReadyDTO costReady = readyAmortization(dateDTO);
            if (costReady.getStatus().equals(false)) {
                return Response.error("成本数据分摊出错,请联系管理员");
            }

            List<Direct> costSource = costReady.getCostSource();
              //  costSource = costSource.stream().filter(t -> t.getDeptCode().equals("6015")).collect(Collectors.toList());
            //拿到分摊表(强制分摊&定向分摊)
            List<RuleCompelamortization> ruleCompelAmortizationList = ruleCompelamortizationMapper.getDirectToCompelRule(dateDTO);
            List<RuleCompelamortization> collect = ruleCompelAmortizationList.stream().filter(t -> t.getType().equals("Compel")).collect(Collectors.toList());
            List<Direct> resultCostSource = getCostSourceByRule(bdDepartmentList, collect, costSource, EnumAmortizationType.DXQZ,dateDTO);
           List<RuleCompelamortization> collect1 = ruleCompelAmortizationList.stream().filter(t -> t.getType().equals("Direct")).collect(Collectors.toList());
            resultCostSource = getCostSourceByRule1(bdDepartmentList, collect1, resultCostSource, EnumAmortizationType.DX);
//            List<Direct> resultCostSource = getCostSourceByRule(bdDepartmentList, ruleCompelAmortizationList, costSource, EnumAmortizationType.DXQZ,dateDTO);

            //插入数据库 AMORTIZATION_DATA 科室分摊前数据
            int deleteRet = amortizationDataMapper.deleteByYearMonth(dateDTO);

            int total = resultCostSource.size();//为防止插入字符超过最大数,分批插入
            int fromIndex = 0;
            List<Direct> insertList = new ArrayList<>();
            for (int i = 0; i < resultCostSource.size(); i++) {
                Direct item = resultCostSource.get(i);
                fromIndex++;
                insertList.add(item);
                if (fromIndex % 20 == 0 && fromIndex <= total) {
                    amortizationDataMapper.insertBatchAmortizationData(insertList);
                    insertList = new ArrayList<>();
                }
            }
            if (CollectionUtils.isNotEmpty(insertList)) {
                amortizationDataMapper.insertBatchAmortizationData(insertList);
            }


            return Response.success("成本数据分摊成功");
        } catch (Exception ex) {
            return Response.error("成本数据分摊出错,请联系管理员");
        }
    }

    public Response XZAmortization(DateDTO dateDTO) {
        dateDTO.setTableIncome("BASE_IN_COME_".concat(String.valueOf(dateDTO.getYear())));
        dateDTO.setTableCost("BASE_COST_".concat(String.valueOf(dateDTO.getYear())));
        dateDTO.setTableCoefficient("ALLOCATION_COEFFICIENT_".concat(String.valueOf(dateDTO.getYear())));
        List<BdDepartment> bdDepartmentList = bdDepartmentMapper.selectList(null);

        List<Direct> resultCostSource = amortizationDataMapper.selectmortizationData(dateDTO);

        //test
//        List<String> deptList =new ArrayList<>();
//        deptList.add("1337");
//        resultCostSource =resultCostSource.stream().filter(t->deptList.contains(t.getDeptCode())).collect(Collectors.toList());

        //行政类分摊
        //拿到分摊表(行政类分摊)
        List<RuleCompelamortization> ruleXZList = ruleCompelamortizationMapper.getXZRule(dateDTO);

        resultCostSource = getCostSourceByRule(bdDepartmentList, ruleXZList, resultCostSource, EnumAmortizationType.XZ,dateDTO);

        //插入数据库 AMORTIZATION_DATA1 科室分摊前数据
        int deleteRet1 = amortizationDataMapper.deleteByYearMonth1(dateDTO);

        int total1 = resultCostSource.size();//为防止插入字符超过最大数,分批插入
        int fromIndex1 = 0;
        List<Direct> insertList1 = new ArrayList<>();
        for (int i = 0; i < resultCostSource.size(); i++) {
            Direct item = resultCostSource.get(i);
            fromIndex1++;
            insertList1.add(item);
            if (fromIndex1 % 20 == 0 && fromIndex1 <= total1) {
                amortizationDataMapper.insertBatchAmortizationData1(insertList1);
                insertList1 = new ArrayList<>();
            }
        }
        if (CollectionUtils.isNotEmpty(insertList1)) {
            amortizationDataMapper.insertBatchAmortizationData1(insertList1);
        }
        return Response.success("success");
    }

    public Response YFAmortization(DateDTO dateDTO) {
        dateDTO.setTableIncome("BASE_IN_COME_".concat(String.valueOf(dateDTO.getYear())));
        dateDTO.setTableCost("BASE_COST_".concat(String.valueOf(dateDTO.getYear())));
        dateDTO.setTableCoefficient("ALLOCATION_COEFFICIENT_".concat(String.valueOf(dateDTO.getYear())));
        List<BdDepartment> bdDepartmentList = bdDepartmentMapper.selectList(null);

        List<Direct> resultCostSource = amortizationDataMapper.selectmortizationData1(dateDTO);

        //医辅类分摊
        //拿到分摊表(医辅类分摊)
        List<RuleCompelamortization> ruleYFList = ruleCompelamortizationMapper.getYFRule(dateDTO);

        resultCostSource = getCostSourceByRule(bdDepartmentList, ruleYFList, resultCostSource, EnumAmortizationType.YF,dateDTO);

        //插入数据库 AMORTIZATION_DATA2 科室分摊前数据
        int deleteRet2 = amortizationDataMapper.deleteByYearMonth2(dateDTO);

        int total2 = resultCostSource.size();//为防止插入字符超过最大数,分批插入
        int fromIndex2 = 0;
        List<Direct> insertList2 = new ArrayList<>();
        for (int i = 0; i < resultCostSource.size(); i++) {
            Direct item = resultCostSource.get(i);
            fromIndex2++;
            insertList2.add(item);
            if (fromIndex2 % 20 == 0 && fromIndex2 <= total2) {
                amortizationDataMapper.insertBatchAmortizationData2(insertList2);
                insertList2 = new ArrayList<>();
            }
        }
        if (CollectionUtils.isNotEmpty(insertList2)) {
            amortizationDataMapper.insertBatchAmortizationData2(insertList2);
        }
        return Response.success("success");
    }

    public Response YJAmortization(DateDTO dateDTO) {
        dateDTO.setTableIncome("BASE_IN_COME_".concat(String.valueOf(dateDTO.getYear())));
        dateDTO.setTableCost("BASE_COST_".concat(String.valueOf(dateDTO.getYear())));
        dateDTO.setTableCoefficient("ALLOCATION_COEFFICIENT_".concat(String.valueOf(dateDTO.getYear())));
        List<BdDepartment> bdDepartmentList = bdDepartmentMapper.selectList(null);

        List<Direct> resultCostSource = amortizationDataMapper.selectmortizationData2(dateDTO);

        //医技特殊处理:收支配比未匹配到的科室归属于上级部门进行分摊
//        List<RuleAmortization> noSZPBList =amortizationDataMapper.listNoSZPB(dateDTO);
        List<OrganizationInfo> noSZPBList = amortizationDataMapper.listNoSZPB(dateDTO);
        LambdaQueryWrapper<BdEnumdetail> ruleWrapper = new LambdaQueryWrapper();
        ruleWrapper.eq(BdEnumdetail::getEdParentCode, "BD_Organization");
        ruleWrapper.eq(BdEnumdetail::getEdExtraFirstCode, "1");
        BdEnumdetail rule = bdEnumdetailMapper.selectOne(ruleWrapper);

        LambdaQueryWrapper<BdOrganization> organizationWrapper = new LambdaQueryWrapper();
        organizationWrapper.eq(BdOrganization::getRuleCode, rule.getEdExtraFirstCode());
        List<BdOrganization> lstOrganization = organizationMapper.selectList(organizationWrapper);

        if (CollectionUtils.isNotEmpty(noSZPBList)) {
            List<Direct> finalResultCostSource = resultCostSource;
            noSZPBList.forEach(item -> {
                List<Direct> matchDirect = finalResultCostSource.stream().filter(t -> t.getDeptCode().equals(item.getDeptCode())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(matchDirect)) {
                    BdOrganization matchBdOrganization = lstOrganization.stream().filter(t -> t.getDeptCode().equals(matchDirect.get(0).getDeptCode())).findFirst().orElse(null);
                    if (matchBdOrganization != null) {
                        //再根据上级科室获取临床属性
                        BdDepartment matchDepartment = bdDepartmentList.stream().filter(t -> t.getDeptCode().equals(matchBdOrganization.getDeptCode())).findFirst().orElse(null);
                        matchDirect.forEach(DItem -> {
                            DItem.setDeptCode(matchBdOrganization.getPDeptCode());
                            DItem.setDeptName(matchBdOrganization.getPDeptName());
                            if (matchDepartment != null) {
                                DItem.setDeptTypeId(matchDepartment.getDeptTypeId());
                                DItem.setDeptTypeName(matchDepartment.getDeptTypeName());
                            }
                        });
                    }
                }
            });
        }


        //test
//        List<String> deptList =new ArrayList<>();
//        deptList.add("2003");
//        deptList.add("210120");
//        resultCostSource =resultCostSource.stream().filter(t->deptList.contains(t.getDeptCode())).collect(Collectors.toList());
        //医技类分摊
        //拿到分摊表(医技类分摊)
        List<RuleCompelamortization> ruleYJList = ruleCompelamortizationMapper.getYJRule(dateDTO);


        resultCostSource = getCostSourceByRule(bdDepartmentList, ruleYJList, resultCostSource, EnumAmortizationType.YJ,dateDTO);

        //插入数据库 AMORTIZATION_DATA3 科室分摊前数据
        int deleteRet3 = amortizationDataMapper.deleteByYearMonth3(dateDTO);

        int total3 = resultCostSource.size();//为防止插入字符超过最大数,分批插入
        int fromIndex3 = 0;
        List<Direct> insertList3 = new ArrayList<>();
        for (int i = 0; i < resultCostSource.size(); i++) {
            Direct item = resultCostSource.get(i);
            fromIndex3++;
            insertList3.add(item);
            if (fromIndex3 % 20 == 0 && fromIndex3 <= total3) {
                amortizationDataMapper.insertBatchAmortizationData3(insertList3);
                insertList3 = new ArrayList<>();
            }
        }
        if (CollectionUtils.isNotEmpty(insertList3)) {
            amortizationDataMapper.insertBatchAmortizationData3(insertList3);
        }
        return Response.success("success");
    }

    private List<Direct> getCostSourceByRule(List<BdDepartment> bdDepartmentList, List<RuleCompelamortization> ruleCompelAmortizationList, List<Direct> costSource, EnumAmortizationType enumType,DateDTO dateDTO) {
        List<Direct> compelSourceCost = new ArrayList<>();
        List<Direct> compelToCost = new ArrayList<>();
        List<String> bdDepartCodeList = bdDepartmentList.stream().map(t -> t.getDeptCode()).distinct().collect(Collectors.toList());
        bdDepartCodeList.add("yjk");
        //拿到分摊表(强制分摊&定向分摊)
        List<RuleCompelamortization> ruleCompelAmortizationList1 = ruleCompelamortizationMapper.getDirectToCompelRule(dateDTO);
        //过滤目标科室
        List<RuleCompelamortization> finalRuleCompelAmortizationList = ruleCompelAmortizationList.stream().filter(t -> bdDepartCodeList.contains(t.getTodeptcode())).collect(Collectors.toList());
        // 过滤源科室
        finalRuleCompelAmortizationList = finalRuleCompelAmortizationList.stream().filter(t -> bdDepartCodeList.contains(t.getDeptcode())).collect(Collectors.toList());
        List<String> costDeptCodeList = costSource.stream().map(t -> t.getDeptCode()).distinct().collect(Collectors.toList());
        // 最终过滤：确保需要分摊数据的源科室通存在bdDpearment和base_cost，目标科室存在于bdDeparment
        finalRuleCompelAmortizationList = finalRuleCompelAmortizationList.stream().filter(t -> costDeptCodeList.contains(t.getDeptcode())).collect(Collectors.toList());
        Map<String, List<RuleCompelamortization>> finalListMap = finalRuleCompelAmortizationList.stream().collect(Collectors.groupingBy(RuleCompelamortization::getDeptcode));
        for (Object key : finalListMap.keySet()) {
            List<RuleCompelamortization> ruleCompelamortizations = finalListMap.get(key);
            // 获取当前源科室对应的成本数据
            List<Direct> thisCostList = costSource.stream().filter(t -> key.equals(t.getDeptCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(thisCostList)) {
                compelSourceCost.addAll(thisCostList);
            }
            for (Direct direct : thisCostList) {
                for (RuleCompelamortization data : ruleCompelamortizations) {
                    Direct toCostInfo = costSource.stream().filter(t -> data.getTodeptcode().equals(t.getDeptCode()) && direct.getAccountCode().equals(t.getAccountCode())).findFirst().orElse(null);
                    if (toCostInfo == null) {
                        toCostInfo = new Direct();
                        BeanUtils.copyProperties(direct, toCostInfo);
                        toCostInfo.setDeptCode(data.getTodeptcode());
                        toCostInfo.setDeptName(data.getTodeptname());
                        toCostInfo.setAmount(BigDecimal.ZERO.setScale(4));
                        toCostInfo.setDirectCost(BigDecimal.ZERO.setScale(4));
                        toCostInfo.setIndirectCost(BigDecimal.ZERO.setScale(4));
                    }
                    //目标科室的分摊源科室
                    toCostInfo.setSourceDept(direct.getDeptCode());
                    toCostInfo.setType(data.getType());
                    toCostInfo.setCoefficient(BigDecimal.valueOf(Double.parseDouble(data.getRulecode())));

                    Direct inertDirect = new Direct();
                    BeanUtils.copyProperties(toCostInfo, inertDirect);
                    List<RuleCompelamortization> collect = ruleCompelAmortizationList1.stream().filter(t -> t.getDeptcode().equals(inertDirect.getDeptCode())&&t.getType().equals("Compel")).collect(Collectors.toList());
                    List<RuleCompelamortization> collect1 = ruleCompelAmortizationList1.stream().filter(t -> t.getDeptcode().equals(inertDirect.getDeptCode())&&t.getType().equals("Direct")).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collect)){
                        for (RuleCompelamortization ruleCompelamortization : collect) {
                            //Direct toCostInfo1 = costSource.stream().filter(t -> ruleCompelamortization.getTodeptcode().equals(t.getDeptCode()) && inertDirect.getAccountCode().equals(t.getAccountCode())).findFirst().orElse(null);
                            Direct toCostInfo1 = null;
                            toCostInfo1 = new Direct();
                            BeanUtils.copyProperties(direct, toCostInfo1);
                            toCostInfo1.setDeptCode(ruleCompelamortization.getTodeptcode());
                            toCostInfo1.setDeptName(ruleCompelamortization.getTodeptname());
                            toCostInfo1.setAmount(BigDecimal.ZERO.setScale(4));
                            toCostInfo1.setDirectCost(BigDecimal.ZERO.setScale(4));
                            toCostInfo1.setIndirectCost(BigDecimal.ZERO.setScale(4));
                            //目标科室的分摊源科室
                            toCostInfo1.setSourceDept(direct.getDeptCode());
                            toCostInfo1.setType(data.getType());
                            toCostInfo1.setCoefficient(inertDirect.getCoefficient().multiply(BigDecimal.valueOf(Double.parseDouble(ruleCompelamortization.getRulecode()))));

                            Direct inertDirect1 = new Direct();
                            BeanUtils.copyProperties(toCostInfo1, inertDirect1);
                            compelToCost.add(inertDirect1);
                        }
                    }else if (CollectionUtils.isNotEmpty(collect1)){
                        for (RuleCompelamortization ruleCompelamortization : collect1) {
                          Direct toCostInfo1 = costSource.stream().filter(t -> ruleCompelamortization.getTodeptcode().equals(t.getDeptCode()) && inertDirect.getAccountCode().equals(t.getAccountCode())).findFirst().orElse(null);
                            if (toCostInfo1 == null) {
                                toCostInfo1 = new Direct();
                                BeanUtils.copyProperties(direct, toCostInfo1);
                                toCostInfo1.setDeptCode(ruleCompelamortization.getTodeptcode());
                                toCostInfo1.setDeptName(ruleCompelamortization.getTodeptname());
                                toCostInfo1.setAmount(BigDecimal.ZERO.setScale(4));
                                toCostInfo1.setDirectCost(BigDecimal.ZERO.setScale(4));
                                toCostInfo1.setIndirectCost(BigDecimal.ZERO.setScale(4));
                            }
                            //目标科室的分摊源科室
                            toCostInfo1.setSourceDept(direct.getDeptCode());
                            toCostInfo1.setType(data.getType());
                            toCostInfo1.setCoefficient(inertDirect.getCoefficient());

                            Direct inertDirect1 = new Direct();
                            BeanUtils.copyProperties(toCostInfo1, inertDirect1);
                            compelToCost.add(inertDirect1);
                        }

                    } else
                    {
                        compelToCost.add(inertDirect);
                    }

                }

            }
        }


        //删除源科室成本数据
        costSource.removeAll(compelSourceCost);
        //这里将目标科室的集合从源成本找到对应的记录再删除(要确保每一项都一样,才能用removeAll)
        List<String> removeDeptList = compelToCost.stream().map(t -> t.getDeptCode()).distinct().collect(Collectors.toList());
        List<Direct> removeDirectList = costSource.stream().filter(t -> removeDeptList.contains(t.getDeptCode())).collect(Collectors.toList());
        //这里过滤原目标科室,后续要用到(累加自己的成本)
        List<Direct> oldToDeptDirectList = costSource.stream().filter(t -> removeDeptList.contains(t.getDeptCode())).collect(Collectors.toList());
        costSource.removeAll(removeDirectList);
        //强制/定向分摊后的成本数据,作为下面分摊的基础成本数据
        List<Direct> resultCostSource = excuteAmortization(costSource, compelSourceCost, compelToCost, oldToDeptDirectList, enumType);
        return resultCostSource;
    }

    private List<Direct> getCostSourceByRule1(List<BdDepartment> bdDepartmentList, List<RuleCompelamortization> ruleCompelAmortizationList, List<Direct> costSource, EnumAmortizationType enumType) {
        List<Direct> compelSourceCost = new ArrayList<>();
        List<Direct> compelToCost = new ArrayList<>();
        List<String> bdDepartCodeList = bdDepartmentList.stream().map(t -> t.getDeptCode()).distinct().collect(Collectors.toList());
        bdDepartCodeList.add("yjk");
        //过滤目标科室
        List<RuleCompelamortization> finalRuleCompelAmortizationList = ruleCompelAmortizationList.stream().filter(t -> bdDepartCodeList.contains(t.getTodeptcode())).collect(Collectors.toList());
        // 过滤源科室
        finalRuleCompelAmortizationList = finalRuleCompelAmortizationList.stream().filter(t -> bdDepartCodeList.contains(t.getDeptcode())).collect(Collectors.toList());
        List<String> costDeptCodeList = costSource.stream().map(t -> t.getDeptCode()).distinct().collect(Collectors.toList());
        // 最终过滤：确保需要分摊数据的源科室通存在bdDpearment和base_cost，目标科室存在于bdDeparment
        finalRuleCompelAmortizationList = finalRuleCompelAmortizationList.stream().filter(t -> costDeptCodeList.contains(t.getDeptcode())).collect(Collectors.toList());
        Map<String, List<RuleCompelamortization>> finalListMap = finalRuleCompelAmortizationList.stream().collect(Collectors.groupingBy(RuleCompelamortization::getDeptcode));
        for (Object key : finalListMap.keySet()) {
            List<RuleCompelamortization> ruleCompelamortizations = finalListMap.get(key);
            // 获取当前源科室对应的成本数据
            List<Direct> thisCostList = costSource.stream().filter(t -> key.equals(t.getDeptCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(thisCostList)) {
                compelSourceCost.addAll(thisCostList);
            }
            for (Direct direct : thisCostList) {
                for (RuleCompelamortization data : ruleCompelamortizations) {
                    Direct toCostInfo = costSource.stream().filter(t -> data.getTodeptcode().equals(t.getDeptCode()) && direct.getAccountCode().equals(t.getAccountCode())).findFirst().orElse(null);
                    if (toCostInfo == null) {
                       toCostInfo = new Direct();
                        BeanUtils.copyProperties(direct, toCostInfo);
                        toCostInfo.setDeptCode(data.getTodeptcode());
                        toCostInfo.setDeptName(data.getTodeptname());
                        toCostInfo.setAmount(BigDecimal.ZERO.setScale(4));
                        toCostInfo.setDirectCost(BigDecimal.ZERO.setScale(4));
                        toCostInfo.setIndirectCost(BigDecimal.ZERO.setScale(4));
                    }
                    //目标科室的分摊源科室
                    toCostInfo.setSourceDept(direct.getDeptCode());
                    toCostInfo.setType(data.getType());
                    toCostInfo.setCoefficient(BigDecimal.valueOf(Double.parseDouble(data.getRulecode())));

                    Direct inertDirect = new Direct();
                    BeanUtils.copyProperties(toCostInfo, inertDirect);
                    compelToCost.add(inertDirect);
                }

            }
        }


        //删除源科室成本数据
        costSource.removeAll(compelSourceCost);
        //这里将目标科室的集合从源成本找到对应的记录再删除(要确保每一项都一样,才能用removeAll)
        List<String> removeDeptList = compelToCost.stream().map(t -> t.getDeptCode()).distinct().collect(Collectors.toList());
        List<Direct> removeDirectList = costSource.stream().filter(t -> removeDeptList.contains(t.getDeptCode())).collect(Collectors.toList());
        //这里过滤原目标科室,后续要用到(累加自己的成本)
        List<Direct> oldToDeptDirectList = costSource.stream().filter(t -> removeDeptList.contains(t.getDeptCode())).collect(Collectors.toList());
        costSource.removeAll(removeDirectList);
        //强制/定向分摊后的成本数据,作为下面分摊的基础成本数据
        List<Direct> resultCostSource = excuteAmortization(costSource, compelSourceCost, compelToCost, oldToDeptDirectList, enumType);
        return resultCostSource;
    }
    /**
     * 分摊前数据准备
     **/
    public CostReadyDTO readyAmortization(DateDTO dateDTO) {
        CostReadyDTO costReady = new CostReadyDTO();

        // 2. 拿到各科室，会计分类下的成本总额
        List<Direct> baseCostList = baseCostMapper.listDeptAndAccountWithSumByDate(dateDTO);

        // 4.拿到所有的会计分类
        BdEnumdetail searchInfo = new BdEnumdetail();
        searchInfo.setEdParentCode("BD_AccountSubject");
        List<BdEnumdetail> accountList = bdEnumdetailMapper.getEnumDetailSource(searchInfo);

        if (CollectionUtils.isEmpty(accountList)) {
            costReady.setStatus(false);
            costReady.setMessage("转换失败:未取到会计分类基础数据");
            costReady.setCostSource(new ArrayList<>());
            return costReady;
        }

        List<Direct> costSource = structureCostSource(baseCostList, accountList);
        costReady.setStatus(true);
        costReady.setMessage("转换成功");
        costReady.setCostSource(costSource);
        return costReady;
    }

    /* 分摊逻辑*/

    /**
     * type :1,行政  2,医辅  3,医技
     */
    public List<Direct> excuteAmortization(List<Direct> oldAmortizationSource, List<Direct> sourceDirect, List<Direct> toDirect, List<Direct> oldToDirectLst, EnumAmortizationType enumType) {
        List<Direct> newAmortizationSource = new ArrayList<>();
        List<Direct> groupDirect = new ArrayList<>();
        sourceDirect.forEach(item -> {
            BigDecimal totalCost = item.getAmount().add(item.getDirectCost()).add(item.getIndirectCost());
            //匹配到目标科室(源科室相同且会计分类相同即可,分摊规则在SQL中已处理)
            List<Direct> matchList = toDirect.stream().filter(t -> t.getSourceDept().equals(item.getDeptCode())
                    && t.getAccountCode().equals(item.getAccountCode())).collect(Collectors.toList());

            if (!CollectionUtils.isEmpty(matchList)) {
                BigDecimal sumTotal = BigDecimal.ZERO;//除最后一项的总金额
                for (int i = 0; i < matchList.size() - 1; i++) {
                    Direct newInfo = new Direct();
                    BeanUtils.copyProperties(matchList.get(i), newInfo);
                    //强制分摊将分摊到的金额作为目标科室的直接成本
                    if ("Compel".equals(newInfo.getType())) {
                        newInfo.setDirectCost(totalCost.multiply(newInfo.getCoefficient()));
                    } else {
                        newInfo.setIndirectCost(totalCost.multiply(newInfo.getCoefficient()));
                    }

                    sumTotal = sumTotal.add(totalCost.multiply(newInfo.getCoefficient()));
                    newAmortizationSource.add(newInfo);
                }
                //最后一条数据赋值
                Direct lastNewInfo = new Direct();
                BeanUtils.copyProperties(matchList.get(matchList.size() - 1), lastNewInfo);
                if ("Compel".equals(lastNewInfo.getType())) {
                    lastNewInfo.setDirectCost(totalCost.subtract(sumTotal));
                } else {
                    lastNewInfo.setIndirectCost(totalCost.subtract(sumTotal));
                }

                newAmortizationSource.add(lastNewInfo);
            }

        });
        //最后一步将相同的目标分摊科室的成本的记录累加在一起
        Map<String, List<Direct>> mapSource = newAmortizationSource.stream().collect(Collectors.groupingBy(t -> t.getDeptCode() + "-" + t.getAccountCode()));
        Iterator<String> it = mapSource.keySet().iterator();

        //判断重复出现的科室
        Map map = new HashMap();
        // 获取组织架构
        List<BdDepartment> bdDepartmentList = bdDepartmentMapper.selectList(null);
        while (it.hasNext()) {
            String key = it.next();

            List<Direct> keyList = mapSource.get(key);
            Direct newInfo = new Direct();
            BeanUtils.copyProperties(keyList.get(0), newInfo);
            BigDecimal directCost = keyList.stream().map(Direct::getDirectCost).reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal inDirectCost = keyList.stream().map(Direct::getIndirectCost).reduce(BigDecimal.ZERO, BigDecimal::add);
            //匹配正确科室类型
            BdDepartment matchDept = bdDepartmentList.stream().filter(t -> t.getDeptCode().equals(newInfo.getDeptCode())).findFirst().orElse(null);
            if (matchDept != null) {
                newInfo.setDeptTypeId(matchDept.getDeptTypeId());
                newInfo.setDeptTypeName(matchDept.getDeptTypeName());
            }


            //这里要从目标科室的源数据查询对应的金额
            Direct matchInfo = oldToDirectLst.stream().filter(t -> (t.getDeptCode() + "-" + t.getAccountCode()).equals(key)).findFirst().orElse(null);
            if (matchInfo != null) {

                if (!map.containsKey(key)&& !enumType.equals(EnumAmortizationType.DX)) {
                    map.put(key, key);
                    newInfo.setDirectCost(matchInfo.getDirectCost().add(directCost));
                    newInfo.setIndirectCost(matchInfo.getIndirectCost().add(inDirectCost));
                } else {
                    newInfo.setDirectCost(directCost);
                    newInfo.setIndirectCost(inDirectCost);
                }
            } else {
                newInfo.setDirectCost(directCost);
                newInfo.setIndirectCost(inDirectCost);
            }

//            //如果科室参与过分摊,将直接成本赋0,
//            if (enumType == EnumAmortizationType.DXQZ) {
//                List<String> amortizationDeptCodeList = sourceDirect.stream().map(t -> t.getDeptCode()).collect(Collectors.toList());
//                String[] splitDept = key.split("-");
//                if (amortizationDeptCodeList.contains(splitDept[0])) {
//                    newInfo.setAmount(BigDecimal.ZERO);
//                    newInfo.setDirectCost(BigDecimal.ZERO);
//                    newInfo.setExtraA("Y");
//                }
//            }
//
//            //如果科室参与过分摊,将直接成本赋0,
//            if (enumType == EnumAmortizationType.YJ) {
//                List<String> amortizationDeptCodeList = sourceDirect.stream().map(t -> t.getDeptCode()).collect(Collectors.toList());
//                String[] splitDept = key.split("-");
//                if (amortizationDeptCodeList.contains(splitDept[0])) {
//                    newInfo.setAmount(BigDecimal.ZERO);
//                    newInfo.setDirectCost(BigDecimal.ZERO);
//                    newInfo.setExtraA("Y");
//                }
//            }
            List<String> amortizationDeptCodeList = sourceDirect.stream().map(t -> t.getDeptCode()).collect(Collectors.toList());
            String[] splitDept = key.split("-");
            if (amortizationDeptCodeList.contains(splitDept[0])) {
                newInfo.setAmount(BigDecimal.ZERO);
                newInfo.setDirectCost(BigDecimal.ZERO);
                newInfo.setExtraA("Y");
            }

            groupDirect.add(newInfo);

        }

        oldAmortizationSource.addAll(groupDirect);
        return oldAmortizationSource;
    }

    /**
     * 构造成本数据
     * // 循环所有科室成本,使其一个科室对应全部的会计分类,每一项都会产生记录,没有匹配的金额为0
     **/
    private List<Direct> structureCostSource(List<Direct> baseCostList, List<BdEnumdetail> accountList) {
        List<Direct> costSource = new ArrayList<>();
        //test
//        List<String> testList =new ArrayList<>();
//        testList.add("4012");
//        baseCostList =baseCostList.stream().filter(t->testList.contains(t.getDeptCode())).collect(Collectors.toList());
        Map<String, List<Direct>> groupCost = baseCostList.stream().collect(Collectors.groupingBy(t -> t.getDeptCode()));
        Iterator<String> it = groupCost.keySet().iterator();

        while (it.hasNext()) {
            String key = it.next();
            List<Direct> keyList = groupCost.get(key);
            //匹配会计分类
            accountList.forEach(aitem -> {
                Direct matchAccountInfo = keyList.stream().filter(t -> t.getAccountCode().equals(aitem.getEdCode())).findFirst().orElse(null);
                if (matchAccountInfo != null) {
                    costSource.add(matchAccountInfo);

                } else {
                    Direct newInfo = new Direct();
                    //如果没有匹配到则构建一条记录,会计分类为aitem,且金额 为0
                    BeanUtils.copyProperties(keyList.get(0), newInfo);
                    newInfo.setAccountCode(aitem.getEdCode());
                    newInfo.setAccountName(aitem.getEdName());
                    newInfo.setAmount(BigDecimal.ZERO);
                    costSource.add(newInfo);
                }


            });
        }
        return costSource;
    }

    public boolean validateCoefficient(List<RuleCompelamortization> ruleCompelAmortizationList) {
        List<RuleCompelamortization> filterList = ruleCompelAmortizationList.stream().filter(t -> t.getRulecode() == null).collect(Collectors.toList());
        return filterList.size() > 0;
    }


    /**
     * 整理数据
     */
    private ReportAmortizationDataVO sortData(List<AmortizationData> dataList, ReportAmortizationDataVO dataVO) {
        for (AmortizationData amortizationData : dataList) {
            String accountCode = amortizationData.getAccountCode();
            BigDecimal amount = amortizationData.getAmount();
            BigDecimal directCost = amortizationData.getDirectCost();
            BigDecimal indirectCost = amortizationData.getIndirectCost();
            switch (accountCode) {
                case "101":
//                    reportAmortizationDataVO.setPersonnel(reportAmortizationDataVO.getPersonnel().add(BigDecimal.valueOf(amount)));
                    dataVO.setDirectPersonnel(dataVO.getDirectPersonnel().add(amount.add(directCost)));
                    dataVO.setIndirectPersonnel(dataVO.getIndirectPersonnel().add(indirectCost));
                    dataVO.setTotalPersonnel((dataVO.getDirectPersonnel().add(dataVO.getIndirectPersonnel())));
                    break;
                case "102":
//                    reportAmortizationDataVO.setSanitaryMaterials(reportAmortizationDataVO.getSanitaryMaterials().add(BigDecimal.valueOf(amount)));
                    dataVO.setDirectSanitaryMaterials(dataVO.getDirectSanitaryMaterials().add(amount.add(directCost)));
                    dataVO.setIndirectSanitaryMaterials(dataVO.getIndirectSanitaryMaterials().add(indirectCost));
                    dataVO.setTotalSanitaryMaterials(dataVO.getDirectSanitaryMaterials().add(dataVO.getIndirectSanitaryMaterials()));
                    break;
                case "103":
//                    reportAmortizationDataVO.setDrug(reportAmortizationDataVO.getDrug().add(BigDecimal.valueOf(amount)));
                    dataVO.setDirectDrug(dataVO.getDirectDrug().add(amount.add(directCost)));
                    dataVO.setIndirectDrug(dataVO.getIndirectDrug().add(indirectCost));
                    dataVO.setTotalDrug(dataVO.getDirectDrug().add(dataVO.getIndirectDrug()));
                    break;
                case "104":
//                    reportAmortizationDataVO.setFixed(reportAmortizationDataVO.getFixed().add(BigDecimal.valueOf(amount)));
                    dataVO.setDirectFixed(dataVO.getDirectFixed().add(amount.add(directCost)));
                    dataVO.setIndirectFixed(dataVO.getIndirectFixed().add(indirectCost));
                    dataVO.setTotalFixed(dataVO.getDirectFixed().add(dataVO.getIndirectFixed()));
                    break;
                case "105":
//                    reportAmortizationDataVO.setIntangible(reportAmortizationDataVO.getIntangible().add(BigDecimal.valueOf(amount)));
                    dataVO.setDirectIntangible(dataVO.getDirectIntangible().add(amount.add(directCost)));
                    dataVO.setIndirectIntangible(dataVO.getIndirectIntangible().add(indirectCost));
                    dataVO.setTotalIntangible(dataVO.getDirectIntangible().add(dataVO.getIndirectIntangible()));
                    break;
                case "106":
//                    reportAmortizationDataVO.setRisk(reportAmortizationDataVO.getRisk().add(BigDecimal.valueOf(amount)));
                    dataVO.setDirectRisk(dataVO.getDirectRisk().add(amount.add(directCost)));
                    dataVO.setIndirectRisk(dataVO.getIndirectRisk().add(indirectCost));
                    dataVO.setTotalRisk(dataVO.getDirectRisk().add(dataVO.getIndirectRisk()));
                    break;
                case "107":
//                    reportAmortizationDataVO.setOther(reportAmortizationDataVO.getOther().add(BigDecimal.valueOf(amount)));
                    dataVO.setDirectOther(dataVO.getDirectOther().add(amount.add(directCost)));
                    dataVO.setIndirectOther(dataVO.getIndirectOther().add(indirectCost));
                    dataVO.setTotalOther(dataVO.getDirectOther().add(dataVO.getIndirectOther()));
                    break;
            }
//            reportAmortizationDataVO.setSum(reportAmortizationDataVO.getSum().add(BigDecimal.valueOf(amount)));
            dataVO.setDirectSum(dataVO.getDirectSum().add(amount.add(directCost)));
            dataVO.setIndirectSum(dataVO.getIndirectSum().add(indirectCost));
            dataVO.setTotalSum(dataVO.getDirectSum().add(dataVO.getIndirectSum()));
        }
        BigDecimal inAll = dataVO.getTotalSum();
        if (inAll.compareTo(BigDecimal.valueOf(0)) > 0) {
            dataVO.setProportionSum(BigDecimal.valueOf(100));
            dataVO.setProportionPersonnel(dataVO.getTotalPersonnel().divide(inAll, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
            dataVO.setProportionDrug(dataVO.getTotalDrug().divide(inAll, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
            dataVO.setProportionFixed(dataVO.getTotalFixed().divide(inAll, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
            dataVO.setProportionIntangible(dataVO.getTotalIntangible().divide(inAll, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
            dataVO.setProportionSanitaryMaterials(dataVO.getTotalSanitaryMaterials().divide(inAll, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
            dataVO.setProportionRisk(dataVO.getTotalRisk().divide(inAll, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
            dataVO.setProportionOther(dataVO.getTotalOther().divide(inAll, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
        }
        return dataVO;
    }
}
